<?php
if(!defined('BASE_DIR'))die('Cannot access the file !');
/**
 * -+-----------------------------------------
 * |PHP Framework
 * |Copyright (c) 2010 jinke.[iblue.cc]
 * |E-mail: mejinke@gmail.com
 * |Date: 2010-04-22
 * |Update: 2011-01-07
 * -+-----------------------------------------
 *
 * Mysql数据库Model模型基础类 ，所有的Mysql数据库的Model层都应继承此类
 * @author jinke
 */
class MysqlModel extends Model
{



	/**
	 * 构造函数 主要用于初始化分配数据库连接资料
	 * @access public
	 * @param mixed $table_name 表名称或MODEL对象[可选]
	 * @param string $app_name 当前所在的应用程序名称
	 */
	public function __construct($table_name = '',$app_name='')
	{
		parent::__construct($table_name, $app_name);
		$this->getAppDefaultDataBaseName($app_name);
		$this->_dbType = MODEL_DB_TYPE_MYSQL;
		$this->getConnect();
		//记录操作数据库的MODEL名称
		Functions::RES('_MODEL_NAME_',$this->_tableName);
		Debug::initClass('MysqlModel.class.php - '.get_class($this));

	}



	/**
	 * 添加数据到库中
	 * @access public
	 * @param array $data 添加的数据 [可选]
     * @param string $table 表名称 [可选]
     * @return mixed 查询结果
	 */
	public function insert(Array $data = null,$table='')
	{
		$this->setDbConnect('insert');
		if (empty($table))
			$table = $this->_tableName;
		Functions::RES('_MODEL_NAME_',strtolower($table));
		//检查如果不是自定义数据,则提交系统获取的数据
		$this->getForm($data);
		if (empty($this->_formData))
			return false;
		//检测是否验证通过
		if($this->_valiSuccess==$this->_valiSum)
		{	
			$this->_db->show_sql = $this->show_sql;
			return $this->_db->insert($this->_data,$table);
		}
		return false;
	 }


	/**
	 * 更新记录
	 * @access	public
	 * @param array $data 将要更新的数据数组 [可选]
	 * @param string $table 表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function update(Array $data = array(),$table='')
	{
		if ($this->adv_where=='')
			message_error('SQL Error','update操作不允许条件为空！',message_debug(debug_backtrace()));
		$this->setDbConnect('update');
		if (empty($table))
			$table = $this->_tableName;
		Functions::RES('_MODEL_NAME_',$table);
		$result = false ;
		//检查如果不是自定义数据,则提交系统获取的数据
		$this->getForm($data);
		if (empty($this->_formData))
			return false;
		//检测是否验证通过
		if($this->_valiSuccess==$this->_valiSum)
		{
			$this->_db->show_sql = $this->show_sql;
			$result = $this->_db->update($this->_data,$table,$this->adv_where);
		}
		$this->clear();
		return $result;
	}


	/**
	 * 删除记录
	 * @access public
	 * @param string $table 表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function remove($table='')
	{	
		if ($this->adv_where=='')
			message_error('SQL Error','remove操作不允许条件为空！',message_debug(debug_backtrace()));
		$this->setDbConnect('remove');
		if (empty($table))
			$table = $this->_tableName;
		Functions::RES('_MODEL_NAME_',$table);
		$this->_db->show_sql = $this->show_sql;
		$result = $this->_db->delete($table,$this->adv_where.' '.$this->adv_in);
		$this->clear();
		return $result;
	}


	/**
	 * 指定字段的值自动增加
	 * @access public
	 * @param string $field 字段名称，注：字段类型必需为int类型
	 * @param int $num 增加的数值 [可选]
	 * @param string $table 表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function autoAdd($field,$num=1,$table='')
	{
		if (empty($table))
			$table = $this->_tableName;
		$this->setDbConnect('update');
		$sql='UPDATE `'.$this->_db->dbName.'`.`'.$table.'` SET `'.$field.'`=`'.$field.'`+'.$num.' '.$this->adv_where;
		Functions::RES('_MODEL_NAME_',$table);
		if ($this->show_sql) die($sql);
		$result = $this->_db->exec($sql);
		return $result;

	}

	/**
	 * 指定字段的值自动减少
	 * @access public
	 * @param string $field	字段名称，注：字段类型必需为int类型
	 * @param int $num	增加的数值 [可选]
	 * @param string $table	表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function autoLessen($field,$num=1,$table='')
	{
		if (empty($table))
			$table = $this->_tableName;
		$this->setDbConnect('update');
		$sql='UPDATE `'.$this->_db->dbName.'`.`'.$table.'` SET `'.$field.'`=`'.$field.'`-'.$num.' '.$this->adv_where;
		Functions::RES('_MODEL_NAME_',$table);
		if ($this->show_sql) die($sql);
		$result = $this->_db->exec($sql);
		return $result;
	}



	/**
	 * 获取一行数据
	 * @access public
	 * @return mixed 查询结果
	 */
	public function getOne()
	{
		$this->adv_limit = ' LIMIT 0,1';
		if($result = $this->select())
			return $result[0];
		else
			return false;
	}

	/**
	 * 获取表中所有数据
	 * @access public
	 * @return mixed 查询结果
	 */
	public function getAll()
	{
		return $this->select();
	}


	/**
	 * 分页获取数据
	 * @access public
	 * @param array|int	 $options
	 * size 每页显示数
	 * nowbar(true|false) 是否显示类似百度页码
	 * select(true|false) 下拉列表风格
	 * args 数组，重置参数
	 * url 重置的URL
	 * @return array
	 */
	public function getPage($option=array())
	{
		//当参数为int size时
		if(!is_array($option))
			$options['size']=$option;
		else
			$options=$option;

		//构造参数
		$sql=false;
		
		//是否自动分页，true时URL存在分页参数时自动分页数 否则始终为第一页的数据
		$autoPage = true; 
		
		isset($options['size'])	? $size = $options['size'] : $size = 10;
		isset($options['nowbar']) ?	$nowbar	= $options['nowbar'] : $nowbar = false;
		isset($options['select']) ? $select	= $options['select'] : $select = false;
		isset($options['args']) ? $args	= $options['args'] : $args = $this->getRouter()->getArgs();
		isset($options['url']) ? $url = $options['url'] : $url = '';
		isset($options['ajax']) ? $ajax = $options['ajax'] : $ajax = false;
		isset($options['parg'])	? $parg	= $options['parg'] : $parg = 'p';
		isset($options['sql']) ? $sql = $options['sql'] : false;
		isset($options['autoPage']) ? $autoPage = $options['autoPage'] : true;
		
		//获取当前页码
		Functions::GET($parg) ? $p = Functions::GET($parg) : $p=1;
		if ($autoPage===false) $p=1;
		
		//总记录数 SQL
		if (!$sql) $sql = $this->_getSQL('',false, true);
		
		$nowbar=true;
		//当前页数据SQL
		if (!isset($options['sql']))
		{
			$this->limit(($p-1)*$size,$size);
			$sql2 =	$this->_getSQL();
		}
		else
			$sql2 = $sql.' LIMIT '.($p-1)*$size.','.$size;
		
		//获取总页
		$sum = $this->query($sql);
		$sum = isset($sum[0]['count']) ? $sum[0]['count']:0;
		
		//URL是否存在页码
		$existsPage = false;
		if (isset($_GET[$parg]))
			$existsPage =true;
			
		//实例化Page对象
		$_p = Functions::LIB('Page');
		$_p->arg=$parg;
		$_p->ajax = $ajax;
		$_p->init($size,$sum,'',$args,$url);

		//获取当前页结果
		$result = $this->setSelectDataType($this->query($sql2));
		if ($existsPage && !isset($result[0]))
			message_404();
			
		//整理数据
		$data['data'] = $result;
		$data['pageArray'] = $_p->diyArray;
		if(!$nowbar)
			$data['html'] = $_p->show();
		else
			$data['html'] = $_p->nowbar();

		if($select)
			$data['html'].=' 跳转至：'.$_p->select();

		//返回内容
		return $data;
	 }


	 /**
	  *	获取记录条数
	  * @access	public
	  * @return int
	  */
	public function getCount()
	{
		return count($this->select());
	}

	/**
	 * 获取最后一次成生的ID
	 * @access public
	 * @return int
	 */
	public function getId()
	{
		return $this->_db->getId();
	}

	/**
	 * 设置需要查询的列
	 * @access	public
	 * @param string $str 查询的列 例：id,name,age
	 * @return this
	 */
	public function find($str)
	{
		if(!empty($str))
			$this->adv_find = DBTool::findFormat($str);
		return $this;
	 }

	/**
	 * 设置查询条件
	 * @access	public
	 * @param string $str 例：id=20
	 * @return this
	 */
	public function where($str)
	{
		$str = DBTool::whereFormat($str);
		if(!empty($str)){
			$this->adv_where = ' WHERE '.$str;
		}
		return $this;
	}
	
	/**
	 * 追加条件
	 * @access public
	 * @param string $str
	 * @return this
	 */
	public function addWhere($str){
		
		$str = DBTool::whereFormat($str);

		if(!empty($str)){
			if ($this->adv_where == '')
				$this->adv_where = ' WHERE '.$str;
			else 
				$this->adv_where .= ' AND '.$str;
		}
		return $this;
	}
	

	/**
	 * 设置IN条件语句
	 * @access public
	 * @param string $finds 字段 例：id
	 * @param array $array 条件值 例：array(1,3,4,23,5)
	 * @param string $type 条件类别  AND 、OR  默认AND
	 * @return this
	 */
	public function in($fields,Array $array = array(),$type = 'AND')
	{	
		if(!empty($array))
		{
			for ($i = 0; $i< count($array); $i++)
			{
				$array[$i] = str_replace("'", "\'", $array[$i]);
				$array[$i] = '\''.$array[$i].'\'';
			}
			if($this->adv_where!='')
				$this->adv_where .= '  '.$type.' `'.$fields.'` IN('.implode(',',$array).') ';
			else
				$this->adv_where = '  WHERE `'.$fields.'` IN('.implode(',',$array).') ';
		}
		else 
			message_error('SQL Error','in条件语句资料不能为空！',message_debug(debug_backtrace()));

		 return $this;
	}


	/**
	 * 设置NOT IN条件语句
	 * @access	public
	 * @param string $finds 字段 例：id
	 * @param array $array 条件值 例：array(1,3,4,23,5)
	 * @param string $type 条件类别  AND 、OR  默认AND
	 * @return this
	 */
	public function notIn($fields,Array $array = array(),$type = 'AND')
	{
		if(!empty($array))
		{
			for ($i = 0; $i< count($array); $i++)
			{
				$array[$i] = str_replace("'", "\'", $array[$i]);
				$array[$i] = '\''.$array[$i].'\'';
			}
			if($this->adv_where!='')
				$this->adv_where .= '  '.$type.'  `'.$fields.'` NOT IN('.implode(',',$array).') ';
			else
				$this->adv_where = '  WHERE `'.$fields.'` NOT IN('.implode(',',$array).') ';
		}
		 return $this;
	}


	/**
	 * 设置排序方式
	 * @access public
	 * @param string $str 例：id desc
	 * @return this
	 */
	public function order($str)
	{
		if(!empty($str))
			$this->adv_order = ' ORDER BY '.$str;
		return $this;
	}

	/**
	 * 设置分组
	 * @access public
	 * @param string $str 字段
	 * @return this
	 */
	public function group($str)
	{
		if(!empty($str))
			$this->adv_group = ' GROUP BY '.$str;
		return $this;
	}

	/**
	 * 获取指定段的数据 Limit
	 * @access public
	 * @param int $start 开始位置
	 * @param int $offset 偏移量
	 * @return this
	 */
	public function limit($start,$offset)
	{
		if(is_numeric($start) && is_numeric($offset))
			$this->adv_limit = ' LIMIT '.$start.','.$offset;
		return $this;
	}

	/**
	 * 执行查询
	 * @access public
	 * @param string $table 表名称［可选］
	 * @return mixed 查询结果
	 */
	public function select($table='')
	{ 
		$sql = $this->_getSQL($table);
		return $this->setSelectDataType($this->query($sql));
	}

	/**
	 * 生成MySQL语句
	 * @access private
	 * @param string $table 表名称［可选］
	 * @param bool $clear 是否清除条件［可选］
	 * @return string SQL语句
	 */
	private function _getSQL($table='',$clear = true,$count = false)
	{
		if (empty($table))
			$table = $this->_tableName;
			
		$adv_findBak = $this->adv_find;
		if ($count===true)
			$this->adv_find = 'count(*) as count';

		$sql ='SELECT '.$this->adv_find.' FROM  `'.$this->_dbName.'`.`'.
			$table.'` '.
			$this->adv_where.
			$this->adv_order.
			$this->adv_limit;
		
		//清理SQL属性
		if($clear)
			$this->clear();
		if($this->show_sql!='')
			die($sql);
			
		$this->adv_find = $adv_findBak;
		
		return $sql;
	}
	
	/**
	 * 获取SQL语句
	 * @access public
	 * @return string
	 */
	public function getSQL()
	{
		return $this->_getSQL('',false);
	}


	/**
	 * 执行SQL 语句
	 * @access public
	 * @param string $sql MySQL语句
	 * @return mixed 查询结果
	 */
	public function query($sql)
	{
		
		if(!empty($this->show_sql)) die($sql);
		Functions::RES('_MODEL_NAME_',$this->_tableName);
	
		if(strpos(' '.strtolower($sql), 'select')>0)
		$this->setDbConnect();
		return $this->_db->query($sql);
	}

	/**
	 * 执行SQL 语句
	 * @access public
	 * @param string $sql MySQL语句
	 * @return mixed 查询结果
	 */
	public function execute($sql)
	{
		Functions::RES('_MODEL_NAME_',$this->_tableName);
		!empty($this->show_sql)	?	die($sql)	:	$result	=	$this->_db->exec($sql);
		return $result;
	}
	
	
	/**
	 * 执行查询后，重置相关属性
	 * @access private
	 * @return void
	 */
	private function clear()
	{
		//重置SQL属性
		$this->adv_find = '*';
		$this->adv_where = '';
		$this->adv_in = '';
		$this->adv_not_in ='';
		$this->adv_order = '';
		$this->adv_group = '';
		$this->adv_limit ='';

	}

}
?>
